package com.ft.oa.service.development.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ft.oa.domain.dev.DevProblem;
import com.ft.oa.domain.dev.DevTask;
import com.ft.oa.domain.dev.WeeklyReport;
import com.ft.oa.domain.development.DevAllocate;
import com.ft.oa.domain.development.DevAllocateStaff;
import com.ft.oa.domain.dto.ApiResult;
import com.ft.oa.domain.dto.development.ReportFillDTO;
import com.ft.oa.domain.dto.sys.SecurityUser;
import com.ft.oa.domain.sys.SysUser;
import com.ft.oa.enums.ManagerEnum;
import com.ft.oa.mapper.dev.DevProblemMapper;
import com.ft.oa.mapper.dev.DevTaskMapper;
import com.ft.oa.mapper.dev.WeeklyReportMapper;
import com.ft.oa.mapper.development.DevAllocateMapper;
import com.ft.oa.mapper.development.DevAllocateStaffMapper;
import com.ft.oa.mapper.sys.SysUserMapper;
import com.ft.oa.service.development.WeeklyReportService;
import com.ft.oa.utils.SecurityUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WeeklyReportServiceImpl implements WeeklyReportService {

    @Resource
    private WeeklyReportMapper weeklyReportMapper;

    @Resource
    private DevAllocateStaffMapper devAllocateStaffMapper;

    @Resource
    private DevAllocateMapper devAllocateMapper;

    @Resource
    private DevTaskMapper devTaskMapper;

    @Resource
    private DevProblemMapper devProblemMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    public ApiResult addWeeklyReport(List<WeeklyReport> weeklyReport) throws Exception {
        if (weeklyReport != null && !weeklyReport.isEmpty()) {
            SecurityUser currentUser = SecurityUtils.getCurrentUser();
            SysUser sysUser = sysUserMapper.selectById(currentUser.getId());
            String nickname = sysUser.getNickname();
            Iterator var1 = weeklyReport.iterator();
            while (var1.hasNext()) {
                WeeklyReport next = (WeeklyReport) var1.next();
                next.setCreateStaffId(currentUser.getId());
                next.setCreateStaff(nickname);
                Date today;
                if(next.getFillingDate()!=null){
                    today = next.getFillingDate();
                    next.setCreateDate(today);
                    next.setUpdateTime(today);
                }else{
                    today = new Date();
                    next.setCreateDate(today);
                    next.setUpdateTime(today);
                }

                next.setState(1);
                //需要加上当前周所对应的周期 以及所在周是当月的第几周  type为0(日报) 1(周报)
                if ("1".equals(next.getType())) {
                    //当前周所对应的周期
                    Map<String, String> weekDate = this.getWeekDate(today, true, next.getType());
                    next.setCycleDate(weekDate.get("weekBegin") + "~" + weekDate.get("weekEnd"));
                    //以及所在周是当月的第几周 本周是当前月的第几周 所在年份 所在月份
                    Map<String, String> weekDate1 = this.getWeekDate(today, false, next.getType());
                    next.setCurrentWeek(this.getWeekByFriday(weekDate1.get("weekEnd")));
                    next.setWeeks(this.getWeeksOfMonth(today).get("weeks"));
                    next.setCurrentYear(weekDate1.get("currentYear"));
                    next.setCurrentMonth(weekDate1.get("currentMonth"));
                } else {
                    //当前周所对应的周期
                    Map<String, String> weekDate = this.getWeekDate(next.getStartDate(), true, next.getType());
                    next.setCycleDate(weekDate.get("weekBegin") + "~" + weekDate.get("weekEnd"));
                    //以及所在周是当月的第几周 本周是当前月的第几周 所在年份 所在月份
                    Map<String, String> weekDate1 = this.getWeekDate(next.getStartDate(), false, next.getType());
                    //next.setCurrentWeek(this.getWeekByFriday(weekDate1.get("weekEnd")));
                    next.setWeeks(this.getWeeksOfMonth(next.getStartDate()).get("weeks"));
                    next.setCurrentYear(weekDate1.get("currentYear"));
                    next.setCurrentMonth(weekDate1.get("currentMonth"));
                }
                weeklyReportMapper.insert(next);
            }
        }
        return ApiResult.simpleSuccess();
    }

    @Override
    public ApiResult updateWeeklyReport(List<WeeklyReport> weeklyReport) {
        weeklyReport.forEach(
                e -> {
                    e.setUpdateTime(new Date());
                    weeklyReportMapper.updateById(e);
                }
        );
        return ApiResult.simpleSuccess();
    }

    @Override
    public ApiResult deleteWeeklyReport(List<WeeklyReport> weeklyReport) {
        weeklyReport.forEach(
                e -> {
                    e.setState(0);
                    e.setUpdateTime(new Date());
                    weeklyReportMapper.updateById(e);
                }
        );
        return ApiResult.simpleSuccess();
    }

    @Override
    public Map<String, Object> fillReportPrepare() throws Exception {
        Map<String, Object> result = new HashMap<>();
        SecurityUser currentUser = SecurityUtils.getCurrentUser();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //通过当前登录人ID 研发需求表查找DevAllocateName和DevAllocateId

        //研发参与人填写周报日报
        //QueryWrapper<DevAllocateStaff> devAllocateStaffQueryWrapper = new QueryWrapper<>();
        //devAllocateStaffQueryWrapper.lambda()
        //        .eq(DevAllocateStaff::getUserId, currentUser.getId());
        //List<DevAllocateStaff> devAllocateStaffs = devAllocateStaffMapper.selectList(devAllocateStaffQueryWrapper);
        //
        //List<ReportFillDTO> devAllocateList = new ArrayList<>();
        //Date date = new Date();
        //boolean isNotFinished = true; //默认没有结束
        //for (DevAllocateStaff devAllocateStaff : devAllocateStaffs) {
        //    DevAllocate devAllocate = devAllocateMapper.selectById(devAllocateStaff.getDevAllocateId());
        //    String finishData = devAllocate.getFinishData();
        //    //判断研发项目是否已经结束
        //    if (StringUtils.isNotBlank(finishData)) {
        //        Date finishDate = sdf.parse(finishData);
        //        isNotFinished = date.before(finishDate);
        //    }
        //    //只有研发审批通过的研发分配 且没有结束 才允许填周日报
        //    if (devAllocate.getApprovalStatus() == 1 && isNotFinished) {
        //        ReportFillDTO reportFillDTO = new ReportFillDTO();
        //        reportFillDTO.setDevAllocateId(devAllocate.getId());
        //        reportFillDTO.setDevAllocateName(devAllocate.getDevAllocateName());
        //        devAllocateList.add(reportFillDTO);
        //    }
        //      isNotFinished = true;
        //}
        //result.put("devAllocateList", devAllocateList);
        //result.put("devAllocateListSize", devAllocateList.size());

        //项目负责人填写
        QueryWrapper<DevAllocate> devAllocateQueryWrapper = new QueryWrapper<>();
        devAllocateQueryWrapper.lambda()
                .eq(DevAllocate::getAllocateProjectManageId, currentUser.getId());
        List<DevAllocate> devAllocates = devAllocateMapper.selectList(devAllocateQueryWrapper);
        boolean isNotFinished = true; //默认没有结束
        List<ReportFillDTO> devAllocateList = new ArrayList<>();
        Date date = new Date();
        for (DevAllocate devAllocate : devAllocates) {
            String finishData = devAllocate.getFinishData();
                //判断研发项目是否已经结束
                if (StringUtils.isNotBlank(finishData)) {
                    Date finishDate = sdf.parse(finishData);
                    isNotFinished = date.before(finishDate);
                }
                //只有研发审批通过的研发分配 且没有结束 才允许填周日报
                if (devAllocate.getApprovalStatus() == 1 && isNotFinished) {
                    ReportFillDTO reportFillDTO = new ReportFillDTO();
                    reportFillDTO.setDevAllocateId(devAllocate.getId());
                    reportFillDTO.setDevAllocateName(devAllocate.getDevAllocateName());
                    devAllocateList.add(reportFillDTO);
                }
                isNotFinished = true;
        }
        result.put("devAllocateList", devAllocateList);
        result.put("devAllocateListSize", devAllocateList.size());

        //研发任务 DevTaskId 和 DevTaskName
        QueryWrapper<DevTask> devTaskQueryWrapper = new QueryWrapper<>();
        devTaskQueryWrapper.lambda()
                .eq(DevTask::getPrincipalStaffId, currentUser.getId());
        List<DevTask> devTasks = devTaskMapper.selectList(devTaskQueryWrapper);
        //过滤掉已经结束的研发任务
        List<DevTask> devTaskCollect = devTasks.stream()
                .filter((devTask) -> devTask.getTaskStatus() != null && devTask.getTaskStatus() != 1)
                .collect(Collectors.toList());
        List<ReportFillDTO> devTaskList = new ArrayList<>();
        for (DevTask devTask : devTaskCollect) {
            ReportFillDTO reportFillDTO = new ReportFillDTO();
            reportFillDTO.setDevTaskId(devTask.getId());
            reportFillDTO.setDevTaskName(devTask.getTaskName());
            DevAllocate devAllocate = devAllocateMapper.selectById(devTask.getDevAllocateId());
            reportFillDTO.setDevAllocateId(devAllocate.getId());
            reportFillDTO.setDevAllocateName(devAllocate.getDevAllocateName());
            devTaskList.add(reportFillDTO);
        }
        result.put("devTaskList", devTaskList);
        result.put("devTaskListSize", devTaskList.size());

        //问题 DevProblemId 和 DevProblemName
        QueryWrapper<DevProblem> devProblemQueryWrapper = new QueryWrapper<>();
        devProblemQueryWrapper.lambda()
                .eq(DevProblem::getPrincipalStaffId, currentUser.getId());
        List<DevProblem> devProblems = devProblemMapper.selectList(devProblemQueryWrapper);
        //过滤掉已经结束的问题
        List<DevProblem> devProblemCollect = devProblems.stream()
                .filter((devProblem) -> devProblem.getProblemStatus() != null && devProblem.getProblemStatus() != 2)
                .collect(Collectors.toList());
        List<ReportFillDTO> devProblemList = new ArrayList<>();
        for (DevProblem devProblem : devProblemCollect) {
            ReportFillDTO reportFillDTO = new ReportFillDTO();
            reportFillDTO.setDevProblemId(devProblem.getId());
            reportFillDTO.setDevProblemName(devProblem.getProblemName());
            DevAllocate devAllocate = devAllocateMapper.selectById(devProblem.getDevAllocateId());
            reportFillDTO.setDevAllocateId(devAllocate.getId());
            reportFillDTO.setDevAllocateName(devAllocate.getDevAllocateName());
            devProblemList.add(reportFillDTO);
        }
        result.put("devProblemList", devProblemList);
        result.put("devProblemListSize", devProblemList.size());
        return result;
    }

    @Override
    public Page<WeeklyReport> pageQueryReport(WeeklyReport weeklyReport) {
        QueryWrapper<WeeklyReport> weeklyReportQueryWrapper = new QueryWrapper<>();
        //默认是看当前用户的周日报
        //if (StringUtils.isBlank(weeklyReport.getCreateStaff())) {
        //    SecurityUser currentUser = SecurityUtils.getCurrentUser();
        //    weeklyReport.setCreateStaffId(currentUser.getId());
        //}
        if(weeklyReport.getDevAllocateId()!=null&&!"".equals(weeklyReport.getDevAllocateId())){
            weeklyReportQueryWrapper.eq("dev_allocate_id",weeklyReport.getDevAllocateId());
        }
        if(weeklyReport.getProjectId()!=null&&!"".equals(weeklyReport.getProjectId())){
            weeklyReportQueryWrapper.eq("project_id",weeklyReport.getProjectId());
        }
        //如果是非管理者只能看自己的
        if(ManagerEnum.GENERAL.toString().equals(SecurityUtils.getCurrentUser().getManager())){
            weeklyReportQueryWrapper.eq("create_staff_id",SecurityUtils.getCurrentUser().getId());
        }else{//如果是管理者可以看所有人的或者某个人的
            weeklyReportQueryWrapper.eq(weeklyReport.getCreateStaffId() != null ,"create_staff_id",weeklyReport.getCreateStaffId());
        }
        weeklyReportQueryWrapper.lambda()
                .eq(WeeklyReport::getType, weeklyReport.getType())
                .eq(weeklyReport.getReportType() != null, WeeklyReport::getReportType, weeklyReport.getReportType())
                .like(StringUtils.isNotBlank(weeklyReport.getDevAllocateName()), WeeklyReport::getDevAllocateName, weeklyReport.getDevAllocateName())
                .like(weeklyReport.getCreateStaff() !=null, WeeklyReport::getCreateStaff, weeklyReport.getCreateStaff())
                .ge(weeklyReport.getStartDate() != null, WeeklyReport::getStartDate, weeklyReport.getStartDate())
                .le(weeklyReport.getEndDate() != null, WeeklyReport::getEndDate, weeklyReport.getEndDate())
                .eq(WeeklyReport::getState, 1);
                //.ne(WeeklyReport::getReportType,0);
        Page<WeeklyReport> page = new Page<>(weeklyReport.getPage(), weeklyReport.getSize());
        return weeklyReportMapper.selectPage(page, weeklyReportQueryWrapper.orderByDesc("create_date"));
    }

    /**
     * 获取一个周的周期
     *
     * @param reportDay 当天时间
     * @param isSunday  true 周一到周日  false 周一到周五
     * @return
     */
    public Map<String, String> getWeekDate(Date reportDay, boolean isSunday, String type) {
        Map<String, String> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(reportDay);
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayWeek == 1) {
            dayWeek = 8;
        }
        int num = 4;
        if (!isSunday) {
            num = 2;
        }
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        cal.add(Calendar.DATE, num + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = sdf.format(sundayDate);
        map.put("weekBegin", weekBegin);
        map.put("weekEnd", weekEnd);
        if ("0".equals(type)) {  //如果是日报那么取汇报日期 周报取周五
            cal.setTime(reportDay);
        }
        map.put("currentYear", String.valueOf(cal.get(Calendar.YEAR)));
        map.put("currentMonth", String.valueOf(cal.get(Calendar.MONTH) + 1));
        String cycleDate = "";
        if (!map.isEmpty()) {
            Iterator it = map.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry obj = (Map.Entry) it.next();
                System.out.println(obj.getKey());
                System.out.println(obj.getKey() + "" + obj.getValue());
            }
            cycleDate = map.get("weekBegin") + "~" + map.get("weekEnd") + "~" + cal.get(Calendar.YEAR) + "~" + (cal.get(Calendar.MONTH) + 1);
            System.out.println(cycleDate);
        }
        return map;
    }

    /**
     * 获取当前月周数
     *
     * @param date 当月某一天，只保留年月日
     * @return
     */
    public Map<String, Integer> getWeeksOfMonth(Date date) throws Exception {
        //当月最后一天，只保留年月日
        HashMap<String, Integer> resultMap = new HashMap<>();
        Map<String, Object> fistDayAndEndDayOfMonth = this.getFistDayAndEndDayOfMonth(date);
        Date lastDate = (Date) fistDayAndEndDayOfMonth.get("lastDay");
        Calendar firstCalendar = Calendar.getInstance();
        Date firstDate = (Date) fistDayAndEndDayOfMonth.get("firstDay");
        firstCalendar.setTime(firstDate);
        Calendar lastCalendar = Calendar.getInstance();
        lastCalendar.setTime(lastDate);
        //获取对应的周数
        int weeks = lastCalendar.get(Calendar.WEEK_OF_MONTH);
        //如果当前月1号是星期天，会按下一周计算，该月周数少算1天，则加1
        if (firstCalendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
            weeks--;
        }
        //如果当前月最后一天是星期天，会按下一周计算，该月周数多算1天，则减1
        if (lastCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && lastCalendar.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) {
            weeks--;
        }
        //周数
        resultMap.put("weeks", weeks);
        return resultMap;
    }

    /**
     * 获取这个月的第一天和最后一天
     *
     * @param date 当天日期
     * @return
     * @throws Exception
     */
    public Map<String, Object> getFistDayAndEndDayOfMonth(Date date) throws Exception {
        HashMap<String, Object> resultMap = new HashMap<>();
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        String formatDay = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
        resultMap.put("lastDay", sdf2.parse(formatDay));

        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        formatDay = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
        resultMap.put("firstDay", sdf2.parse(formatDay));
        return resultMap;
    }


    /**
     * 获取当前日期是本月的第几周(通过本月有几个周五来判断)
     *
     * @param dateStr 日期(格式：yyyy-MM-dd)
     * @return 第n周
     * @throws Exception
     */
    public int getWeekByFriday(String dateStr) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
        Date date = sdf.parse(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 获得当前日期是一个星期的第几天
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值，变为周一
        calendar.add(Calendar.DATE, calendar.getFirstDayOfWeek() - day);
        calendar.add(Calendar.DATE, 4);// 加四天天变为周五
        //得到传入日期所在周的周五
        String wed = sdf.format(calendar.getTime());
        // 本月份的天数
        int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        int wek = 5;//判断是周五
        int index = 0;//本月的第几个周五
        List list = new ArrayList();
        for (int i = 1; i <= days; i++) {
            calendar.set(Calendar.DAY_OF_MONTH, i);
            int weekd = calendar.get(Calendar.DAY_OF_WEEK) - 1;// 注意,Calendar对象默认星期天为1
            if (weekd == wek) {
                String aaa = sdf.format(calendar.getTime());
                list.add(aaa);
                if (wed.equals(aaa)) {
                    index = list.size();
                }
            }
        }
        return index;
    }

    public static void main(String[] args) throws Exception {
        WeeklyReportServiceImpl weeklyReportService = new WeeklyReportServiceImpl();
        String time02 = "2022-01-31";
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        Date date2 = sdf2.parse(time02);
        //Map<String, Integer> weeksOfMonth = weeklyReportService.getWeeksOfMonth(date2);
        //if(!weeksOfMonth.isEmpty()) {
        //    Iterator it = weeksOfMonth.entrySet().iterator();
        //    while (it.hasNext()) {
        //        Map.Entry obj = (Map.Entry) it.next();
        //        System.out.println(obj.getKey()+"     "+obj.getValue());
        //    }
        //}
        //Calendar calendar = Calendar.getInstance();
        //calendar.setTime(date2);
        //System.out.println(calendar.get(Calendar.WEEK_OF_MONTH));
        ////WeeklyReportServiceImpl weeklyReportService = new WeeklyReportServiceImpl();
        Map<String, String> weekDate = weeklyReportService.getWeekDate(date2, false, "1");
        //System.out.println(calendar.get(Calendar.YEAR));
        //System.out.println(calendar.get(Calendar.MONDAY)+1);
        int weekEnd = weeklyReportService.getWeekByFriday(weekDate.get("weekEnd"));
        System.out.println("----------------------------");
        System.out.println(weekEnd);
        System.out.println("----------------------------");
        if (!weekDate.isEmpty()) {
            Iterator it = weekDate.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry obj = (Map.Entry) it.next();
                System.out.println(obj.getKey());
                System.out.println(obj.getKey() + "" + obj.getValue());
            }
        }
        //System.out.println(weekDate.get("weekBegin")+"~"+weekDate.get("weekEnd"));

        //
        //int weekByFriday = weeklyReportService.getWeekByFriday(date2);
        //System.out.println("weekByFriday:"+weekByFriday);
        //String cycleDate = weeklyReportService.getWeekDate(date2);
        //System.out.println(cycleDate);
        //
        //String[] weeks = { "日", "一", "二", "三", "四", "五", "六" };
        //Calendar c = Calendar.getInstance();
        //c.setTime(date2);
        //c.setFirstDayOfWeek(Calendar.FRIDAY);
        //int week = c.get(Calendar.WEEK_OF_MONTH);//获取是本月的第几周
        //int day = c.get(Calendar.DAY_OF_WEEK);//获致是本周的第几天地, 1代表星期天...7代表星期六
        //System.out.println("今天是本月的第" + week + "周");
        //System.out.println("今天是星期" + weeks[day-1]);
        //
        //Calendar cal = Calendar.getInstance();
        //cal.set(Calendar.YEAR, date2.getYear());
        //cal.set(Calendar.MONTH, date2.getMonth());
        //cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DATE));
        //System.out.println("结束时间"+new SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime()));
        //cal.set(Calendar.DAY_OF_MONTH,cal.getMinimum(Calendar.DATE));
        //System.out.println("开始时间"+new SimpleDateFormat( "yyyy-MM-dd ").format(cal.getTime()));
        //
        //Map<String, Object> fistDayAndEndDayOfMonth = weeklyReportService.getFistDayAndEndDayOfMonth(date2);
        //if(!fistDayAndEndDayOfMonth.isEmpty()) {
        //    Iterator it = fistDayAndEndDayOfMonth.entrySet().iterator();
        //    while (it.hasNext()) {
        //        Map.Entry obj = (Map.Entry) it.next();
        //        System.out.println(obj.getKey());
        //        System.out.println(obj.getKey()+""+obj.getValue());
        //    }
        //}
    }
}
